﻿using DNFImagePacks2Manager.Helpers;
using Microsoft.UI;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using SharpCompress.Common;
using SharpCompress.Writers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;

namespace DNFImagePacks2Manager.Pages
{
    public sealed partial class ProcessExportPage : Page
    {
        private readonly DispatcherQueue _dispatcherQueue;

        public ProcessExportPage()
        {
            InitializeComponent();
            _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
        }

        public async Task StartExportTask(Dictionary<string, string> compressFiles, string exportFile)
        {

            try
            {
                string? path = Path.GetDirectoryName(exportFile);
                if(path == null)
                {
                    await DispatchToUI(() =>
                    {
                        TitleTextBlock.Text = $"获取导出路径信息失败";
                    });
                    return;
                }
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                if (File.Exists(exportFile)) {
                    File.Delete(exportFile);
                }

                using (var stream = File.OpenWrite(exportFile))
                using (var writer = WriterFactory.Open(stream, ArchiveType.Zip, new WriterOptions(CompressionType.Deflate) {
                    ArchiveEncoding = new ArchiveEncoding()
                    {
                        Forced = Encoding.UTF8
                    }
                }))
                {
                    int current = 0;
                    int total = compressFiles.Count;
                    foreach (var compressFile in compressFiles)
                    {
                        current++;
                        string compressPath = compressFile.Key;
                        string filePath = compressFile.Value;
                        string fileName = Path.GetFileName(compressPath);
                        await DispatchToUI(() =>
                        {
                            UpdateProcess(fileName, current, total);
                        });

                        if (!File.Exists(filePath))
                        {
                            await DispatchToUI(() =>
                            {
                                AddLog($"{filePath} 文件不存在，跳过", "red");
                            });
                            continue;
                        }

                        try
                        {
                            writer.Write(compressPath, filePath);
                            await DispatchToUI(() =>
                            {
                                AddLog($"{fileName} 文件压缩完成", "green");
                            });
                            continue;
                        }
                        catch (Exception ex) {
                            await DispatchToUI(() =>
                            {
                                AddLog($"{fileName} 文件压缩失败: {ex.Message}", "red");
                            });
                            continue;
                        }
                    }
                    await DispatchToUI(() =>
                    {
                        AddLog($"压缩包压缩完成", "green");
                    });
                }

                await DispatchToUI(async () =>
                {
                    TitleTextBlock.Text = "压缩包导出完成";
                    CurrentFileText.Text = $"当前文件: 无";

                    ContentDialogResult result = await DialogHelper.ShowConfirmDialog(
                        this,
                        "压缩包导出完成",
                        "是否打开导出目录"
                    );
                    if (result == ContentDialogResult.Primary)
                    {
                        try
                        {
                            ConsoleHelper.OpenFolderAndSelectFile(exportFile);
                        }
                        catch (Exception) { }
                    }
                });
            }
            catch (Exception ex) {
                await DispatchToUI(() => 
                {
                    TitleTextBlock.Text = "压缩包导出失败";
                    CurrentFileText.Text = $"当前文件: 无";
                    DialogHelper.ShowErrorMessage(this, $"压缩包导出失败: {ex.Message}");
                });
            }
        }

        private Task DispatchToUI(Action uiAction)
        {
            var tcs = new TaskCompletionSource<bool>();
            if (_dispatcherQueue.TryEnqueue(() =>
            {
                try
                {
                    uiAction();
                    tcs.SetResult(true);
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            }))
            {
                return tcs.Task;
            }
            else
            {
                return Task.FromException(new InvalidOperationException("UI 线程已关闭，无法更新进度"));
            }
        }

        private void UpdateProcess(string name, int current, int total)
        {

            CurrentFileText.Text = $"当前文件: {name}";
            FileProgressText.Text = $"处理文件: {current}/{total}";
            FileProgressBar.Value = Math.Round((double)current / total * 100, 1);
        }

        private void AddLog(string content, string color)
        {
            var logItem = new TextBlock
            {
                Text = $"[{DateTime.Now:HH:mm:ss}] {content}",
                Margin = new Thickness(0, 3, 0, 3),
                TextWrapping = TextWrapping.Wrap,
                FontSize = 12,
                Foreground = color.ToLower() switch
                {
                    "red" => new SolidColorBrush(Colors.Red),
                    "green" => new SolidColorBrush(Colors.Green),
                    "blue" => new SolidColorBrush(Colors.Blue),
                    _ => new SolidColorBrush(Colors.Gray),
                }
            };

            LogPanel.Children.Add(logItem);

            LogScrollViewer.ScrollToVerticalOffset(LogScrollViewer.ScrollableHeight);
        }
    }
}
